var Command = require('./public/command.js');
var config = require('./config');
var mongoose = require('mongoose');
var async = require('async');

//mongoose
var url = 'mongodb://' + config.host + '/' + config.db;
mongoose.connect(url, {
    user : config.user,
    pass : config.pwd
});


require('./models/user.js');
require('./models/battle.js');
require('./models/store.js');

var User = mongoose.model('User');
var Battle = mongoose.model('Battle');
var Store = mongoose.model('Store');

var SocketIo = function(server){

    var io = require('socket.io')(server);

    io.on('connection', function(socket){

        //客户端准备好了
        socket.on(Command.CLIENT_READY, function(data){
            var userId = data.userId;
            socket.userId = userId;

            console.log('用户:' + userId + ' 连接上了');
        });

        //断开连接了
        socket.on('disconnect', function () {
            var userId = socket.userId;
            console.log('用户:' + userId + ' 断开了');

            //如果用户掉线了，则把该用户创建的正在进行的对战和尚未开始的对战删除，并告知其他用户
            Battle.find({
                owner : userId,
                status : {
                    $in : ['N', 'I']
                }
            }).populate('store').exec(function(err, battles){
                console.log('对战列表：' + battles);
                async.eachSeries(battles, function(battle, callback){

                    var storeId = battle.store._id;
                    var battleId = battle._id;
                    Battle.findByIdAndRemove(battleId, {}, function(err){

                        console.log('用户Id' + userId);
                        console.log('题库Id ' + storeId);
                        console.log('对战Id ' + battleId);

                        //告诉其他对战人员这个对战已经被删除掉了
                        io.sockets.emit(Command.OWNER_FLEE_BATTLE, {
                            userId : userId,
                            storeId : storeId,
                            battleId : battleId
                        });

                        callback(err);
                    });
                }, function(err){
                    console.log('删除尚未开始的对战结束 ' + err);
                    console.log('从自己正在参与的对战中删除自己信息');
                    //找到本人参与的正在进行或尚未开始的对战，然后从中删除自己的信息
                    Battle.find({
                        users : userId,
                        status : {
                            $in : ['N', 'I']
                        }
                    }).populate('users').exec(function(err, bs){
                        async.eachSeries(bs, function(b, callback){
                            //从中删除自己
                            for(var i = 0; i < b.users.length; i++){
                                var u = b.users[i];
                                if(u._id == userId){
                                    b.users.splice(i, 1);
                                    console.log('从对战的参战人员中删除自己:' + userId);
                                }
                            }
                            b.save(function(err){
                                callback(err);
                            });
                        }, function(err){
                            if(err) throw err;
                            //当用户掉线的时候提示其他用户这个用户已经掉线了
                            io.sockets.emit(Command.USER_FIEE_BATTLE, {
                                userId : userId
                            });
                        })
                    });
                });
            });
        });

        //监听用户ping命令
        socket.on(Command.PING, function(){
            console.log('用户:' + socket.userId + ' 发来ping命令');
        });

        //某用户进入题库了
        socket.on(Command.JOIN_STORE, function(data){
            var storeId = data.storeId;
            console.log('用户:' + socket.userId + ' 进入题库: '+ storeId);
        });

        //某用户新建了一个挑战
        socket.on(Command.NEW_BATTLE, function(data){
            var storeId = data.storeId;
            var battleId = data.battleId;
            console.log('用户:' + socket.userId + ' 在题库: '+ storeId + ' 建立挑战: ' + battleId);

            //进入对战房间
            var rid = storeId + '-' + battleId;
            socket.join(rid);

            //告诉其他人有新的挑战创建
            socket.broadcast.emit(Command.NEW_BATTLE_BROADCAST, {
                userId : socket.userId,
                storeId : storeId,
                battleId : battleId
            });
        });

        //某用户新建了一个练习
        socket.on(Command.NEW_PRACTICE, function(data){
            var storeId = data.storeId;
            var practiceId = data.practiceId;
            console.log('用户:' + socket.userId + ' 在题库: '+ storeId + ' 建立练习: ' + practiceId);
        });

        //某用户加入了一个挑战
        socket.on(Command.JOIN_BATTLE, function(data){
            var storeId = data.storeId;
            var battleId = data.battleId;
            console.log('用户:' + socket.userId + ' 在题库: '+ storeId + ' 加入挑战: ' + battleId);

            //对战房间ID
            var rid = storeId + '-' + battleId;
            socket.join(rid, function(){
                console.log('用户:' + socket.userId + ' 进入房间: ' + rid);
                //向该房间内的其他用户广播一条消息,有人加入了对战
                socket.broadcast.to(rid).emit(Command.USER_JOIN_BATTLE, {
                    userId : socket.userId,
                    storeId : storeId,
                    battleId : battleId
                });
            });
            //向所有连接广播该对战开始了
            socket.broadcast.emit(Command.JOIN_BATTLE_BROADCAST, {
                userId : socket.userId,
                storeId : storeId,
                battleId : battleId
            });
        });

        //对战创建人开始了对战，通知其他参战人员准备
        socket.on(Command.READY_BATTLE, function(data) {
            var rid = data.rid;
            //告诉其他参战人员准备
            socket.broadcast.to(rid).emit(Command.READY_BATTLE);
        });

        //对战创建人开始了对战，通知其他参战人员开始
        socket.on(Command.START_BATTLE, function(data){
            var rid = data.rid;
            var storeId = data.storeId;
            var battleId = data.battleId;
            console.log('用户:' + socket.userId + ' 开始了对战: ' + rid );
            //告诉其他参战人员开展
            socket.broadcast.to(rid).emit(Command.START_BATTLE, {
                userId : socket.userId,
                storeId : storeId,
                battleId : battleId
            });
            //向所有连接广播该对战开始了
            socket.broadcast.emit(Command.START_BATTLE_BROADCAST, {
                userId : socket.userId,
                storeId : storeId,
                battleId : battleId
            });
        });

        //某用户答题发来一份战报
        socket.on(Command.BATTLE_NEWS, function(data){

            var rid = data.rid;
            var userId = data.userId;
            var score = data.score;
            var proce = data.proce; //用户剩余题量
            console.log('用户:' + userId + ' 对战房间: ' + rid + ' 得分: ' + score);
            //告诉该对战房间内其他用户该战报内容
            socket.broadcast.to(rid).emit(Command.BATTLE_NEWS, {
                userId : userId,
                score : score,
                proce : proce
            });
        });

        //对战创建人逃离了对战
        socket.on(Command.OWNER_FLEE_BATTLE, function(data){
            var rid = data.rid;
            var userId = data.userId;
            var battleId = data.battleId;
            var storeId = data.storeId;

            console.log('用户(对战创建人):' + socket.userId + ' 逃离了对战房间: ' + rid);
            //告诉该对战房间内其他用户该战报内容
            socket.broadcast.to(rid).emit(Command.OWNER_FLEE_BATTLE, {
                userId : socket.userId
            });

            //离开对战房间
            socket.leave(rid);

            //向所有连接广播该对战开始了
            socket.broadcast.emit(Command.STOP_BATTLE_BROADCAST, {
                userId : userId,
                storeId : storeId,
                battleId : battleId
            });
        });

        //某用户逃离对战
        socket.on(Command.USER_FIEE_BATTLE, function(data){
            var rid = data.rid;
            var userId = socket.userId;
            var userName = data.userName;
            console.log('用户:' + socket.userId + ' 逃离了对战房间: ' + rid);

            //找到本人参与的正在进行或尚未开始的对战，然后从中删除自己的信息
            Battle.find({
                users : userId,
                status : {
                    $in : ['N', 'I']
                }
            }).populate('users').exec(function(err, bs){
                async.eachSeries(bs, function(b, callback){
                    //从中删除自己
                    for(var i = 0; i < b.users.length; i++){
                        var u = b.users[i];
                        if(u._id == userId){
                            b.users.splice(i, 1);
                            console.log('从对战的参战人员中删除自己:' + userId);
                        }
                    }
                    b.save(function(err){
                        callback(err);
                    });
                }, function(err){
                    if(err) throw err;
                    //当用户掉线的时候提示其他用户这个用户已经掉线了
                    io.sockets.emit(Command.USER_FIEE_BATTLE, {
                        userId : userId,
                        userName : userName
                    });
                    //离开对战房间
                    socket.leave(rid);
                })
            });

            //告诉该对战房间内其他用户该战报内容
            /*
            socket.broadcast.to(rid).emit(Command.USER_FIEE_BATTLE, {
                userId : socket.userId,
                userName : userName
            });
            //离开对战房间
            socket.leave(rid);
            */
        });

        //对某用户使用拖延道具
        socket.on(Command.DEFER_USER, function(data){
            var rid = data.rid;
            var userId = data.userId;
            var userName = data.userName;
            var toUser = data.toUser;
            console.log('用户:' + userId + ' 在对战房间: ' + rid + ' 对用户:' + toUser + ' 使用拖延道具');
            //告诉该对战房间内其他用户该战报内容
            socket.broadcast.to(rid).emit(Command.DEFER_USER, {
                userId : userId,
                userName : userName,
                toUser : toUser
            });
        });

        //对战结束
        socket.on(Command.STOP_BATTLE, function(data){
            var rid = data.rid;
            var userId = data.userId;
            var battleId = data.battleId;
            var storeId = data.storeId;
            console.log('用户:' + socket.userId + ' 对战: ' + rid + ' 结束了');
            //告诉该对战房间内其他用户对战结束了
            socket.broadcast.to(rid).emit(Command.STOP_BATTLE, {
                userId : userId,
                battleId : battleId,
                storeId : storeId
            });
            //向所有连接广播该对战开始了
            socket.broadcast.emit(Command.STOP_BATTLE_BROADCAST, {
                userId : userId,
                storeId : storeId,
                battleId : battleId
            });
        });

        //对战被删除
        socket.on(Command.DELETE_BATTLE, function(data){
            var rid = data.rid;
            var userId = data.userId;
            var battleId = data.battleId;
            var storeId = data.storeId;
            console.log('用户:' + userId + ' 删除了对战: ' + battleId);
            //告诉该对战房间内其他用户该战报内容
            socket.broadcast.to(rid).emit(Command.OWNER_FLEE_BATTLE, {
                userId : socket.userId
            });
            socket.leave(rid);
            socket.broadcast.emit(Command.DELETE_BATTLE_BROADCAST, {
                userId : userId,
                storeId : storeId,
                battleId : battleId
            });
        });

    });

};

module.exports = SocketIo;